/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package milkyway.hightech.banking;

import milkyway.hightech.conditions.InvestmentAccountConditions;
import milkyway.hightech.exceptions.TransactionNotAllowedException;
import milkyway.hightech.money.Currency;
import milkyway.hightech.money.Money;
import milkyway.hightech.timer.TimeEmitter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.Observable;
import milkyway.hightech.exceptions.NotEnoughMoneyException;

/**
 *
 * @author michael
 */
public class InvestmentAccount extends Account
{
    private InvestmentAccountConditions conditions;
    
    private int period;
    	
    /**
     * creates a new investment account
     * @param accountNumber the number of this account
     * @param accountHolder the holder of this account
     * @param accountType the description of this account
     * @param creditInterest the current rate of credit interest
     * @param debitInterest the current rate of credit interest
     */
    public InvestmentAccount(int accountNumber, String accountHolder, Currency currency, InvestmentAccountConditions conditions, Calendar calendar)
    {
	super(accountNumber, accountHolder, currency, calendar);
	this.conditions = conditions;
	this.period = conditions.getContractPeriod() * 30;
    }
    
    @Override
    public void update(Observable o, Object obj)
    {
	setChanged();
	
	period--;
	
	if(period == 0)
	    notifyObservers(this);
    }

    //interfaces
    
    public InvestmentAccountConditions getAccountConditions()
    {
	return conditions;
    }
    
    public void renewContract()
    {
	this.calendar = TimeEmitter.getInstance().getCalendar();
	period = conditions.getContractPeriod() * 30;
    }

    /**
     * pays the current interest on credit
     */
    @Override
    public void payInterest()
    {
	BigDecimal d = new BigDecimal(getAccountBalance().divide(BigInteger.valueOf(100)));
	d = d.multiply(BigDecimal.valueOf(conditions.getCreditInterest()));
	this.enterOnCredit(new Money(d.toBigInteger(), money.getCurrency()), "pay interest");

	if(getAccountBalance().compareTo(new BigInteger("0")) == 1)
	    renewContract();
    }
    
    /**
     * enters the given amount on debit and assures that
     * the account ballance will not be less than zero
     * @param amount
     * @param reasonOfTransfer
     */
    @Override
    public void enterOnCredit(Money amount, String reasonOfTransfer)
    {
	if(amount.getValue().signum() <= 0 || period > 0 && period < conditions.getContractPeriod() * 30)
	    throw new TransactionNotAllowedException(getAccountNumber() + ", on " + TimeEmitter.getInstance().getCalendar().getTime()
		    + ", could not be applied");
	else
	    update(1, amount, reasonOfTransfer);
    }

    /**
     * enters the given amount on debit and assures that
     * the account ballance will not be less than zero
     * @param amount the amount of money which should be entered on debid
     * @param reasonOfTransfer the description of this transaction
     */
    @Override
    public void enterOnDebit(Money amount, String reasonOfTransfer)
    {
	BigInteger b = getAccountBalance();
	int i = amount.getValue().compareTo(b);

	if(amount.getValue().signum() == -1 || period > 0 && period < conditions.getContractPeriod() * 30)
	    throw new TransactionNotAllowedException(getAccountNumber() + ", on " + TimeEmitter.getInstance().getCalendar().getTime()
		    + ", could not be applied");
	else if(i == 1)
	    throw new NotEnoughMoneyException(getAccountNumber() + ", on " + TimeEmitter.getInstance().getCalendar().getTime()
		    + ", could not be applied");
	else
	    update(-1, amount, reasonOfTransfer);
    }

    //end of interfaces
}